% Form of board, r for red, o for vacant spaces, b for blue. Starting is
% [r, r, r, r, o, b, b, b, b]

% A legal jump.
jump([r, o | T], [o, r | T]).
jump([o, b | T], [b, o | T]).
jump([r, b, o | T], [o, b, r | T]).
jump([o, r, b | T], [b, r, o | T]).
jump([H|T1], [H|T2]) :- jump(T1,T2).

% Series of legal boards.
series(From, To, [From, To]) :- jump(From, To).
series(From, To, [From, By | Rest])
	:- jump(From, By), 
	   series(By, To, [By | Rest]).

% Print a series of boards.  This puts one board per line and looks a lot
% nicer than the jumble that appears when the system simply beltches out
% a list of boards.  The write_ln predicate is a built-in which always
% succeeds (is always satisfied), but prints as a side-effect.  Therefore
% print_series(Z) will succeed with any list, and the members of the list
% will be printed, one per line, as a side-effect of that success.
print_series_r([]) :- 
    write_ln('*******************').
print_series_r([X|Y]) :- write_ln(X), print_series_r(Y).
print_series(Z) :- 
    write_ln('\n*******************'),
    print_series_r(Z).

% A solution.
solution(L) :- series([r,r,r,r,o,b,b,b,b], [b,b,b,b,o,r,r,r,r], L).

% Find a print the first solution.  
solve :- solution(X), print_series(X).

% Find all the solutions.
solveall :- solve, fail.

% This finds each solution with stepping.
solvestep(Z) :- Z = next, solution(X), print_series(X).
